/*
 * @Author: xiaosihan
 * @Date: 2021-04-18 14:09:03
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-11-07 19:29:49
 */

import Object3D from "../Object3D/Object3D";
import Object3DComponent, { Object3DComponentProps } from "../Object3D/Object3DComponent";
import { Object3DEvent } from "../Renderer/type";
import Transition from "../xrt_util/Transition";

export interface CameraProps extends Object3DComponentProps {

    fov?: number, // 广角角度
    near?: number, // 近景面
    far?: number, // 远景面
}

interface State { }

export default class Camera extends Object3DComponent<CameraProps, State> {
    constructor(props: CameraProps) {
        super(props);
    }

    static defaultProps = {
        fov: 50, // 广角角度
        near: 0.01, // 近景面
        far: 1500, // 远景面
    }

    // 有过渡动画的参数
    Tparam = new Transition();

    // componentBeforeRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera) {
    //     this.setCameraParam();
    // }

    // 设置相机的过渡参数
    setCameraTransParam() {
        const { fov = 50, near = 1, far = 1500 } = this.props;

        this.Tparam.set({ fov, near, far });
    }

    // 设置相机的参数
    setCameraParam = () => {
        const { camera } = this.context;

        let keepRun = false;

        if (!this.Tparam.isDone()) {
            const { fov, near, far } = this.Tparam.getJson();

            Object.assign(camera, { fov, near, far });
            camera.updateProjectionMatrix();
            keepRun = true;
        }

        if (this.props.lookAt) {
            camera.lookAt(this.lookAtPosition);
            keepRun = true;
        } else {
            camera.matrixWorld.multiplyMatrices(this.object3d.matrixWorld, camera.matrix);
            camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
        }

        // 当不需要 继续执行事件时 从监听中移除
        if (!keepRun) {
            this.object3d.removeEventListener(Object3DEvent.BEFORE_RENDER, this.setCameraParam);
        }
    }

    componentDidMount() {

        const { camera } = this.context;

        this.object3d.add(camera as unknown as Object3D);

        // 设置相机的过渡参数
        this.setCameraTransParam();

        // 设置参数
        this.setCameraParam();

        // 每帧渲染前 设置一次相机的参数
        this.object3d.addEventListener(Object3DEvent.BEFORE_RENDER, this.setCameraParam);
    }

    componentDidUpdate() {

        // 设置相机的过渡参数
        this.setCameraTransParam();

        // 每帧渲染前 设置一次相机的参数 先删后加 避免重复监听
        this.object3d.removeEventListener(Object3DEvent.BEFORE_RENDER, this.setCameraParam);
        this.object3d.addEventListener(Object3DEvent.BEFORE_RENDER, this.setCameraParam);

    }

    componentWillUnmount() {
        this.object3d.removeEventListener(Object3DEvent.BEFORE_RENDER, this.setCameraParam);
    }

}